import React from 'react';
import { Divider, Button } from 'antd';

interface ThemeType {
  color: string;
  background: string;
}

export const ThemeContext = React.createContext<ThemeType | null>(null);
ThemeContext.displayName = 'ThemeContext'; // devTools

const ThemeProvider = ThemeContext.Provider; // 提供者
const ThemeConsumer = ThemeContext.Consumer; // 订阅消费者

function ConsumerCom() {
  console.log('ConsumerCom ConsumerCom ConsumerCom');
  return (
    <>
      <ThemeConsumer>
        {(contextValue) => {
          return (
            <>
              {/* <ConsumerComChild {...contextValue} /> */}
              <MemoConsumerComChild {...contextValue} />
            </>
          );
        }}
      </ThemeConsumer>
      <Son1 />
      <Son2 />
    </>
  );
}

const MemoConsumerCom = React.memo(ConsumerCom);

function FuncSon() {
  const contextValue = React.useContext(ThemeContext);
  const { color, background } = contextValue!;
  return (
    <div style={{ color, background }}>
      <p>useContext 消费者</p>
    </div>
  );
}

const NewFuncSon = () => {
  return (
    <>
      <FuncSon />
      <Son2 />
      <Son1 />
    </>
  );
};

const MemoNewFuncSon = React.memo(() => <NewFuncSon />);

// 生产者
export default function CreateContextDemo() {
  const [contextValue, setContextValue] = React.useState({ color: '#f40', background: '#fff' });
  // 修改主题
  const changeContext = () => {
    setContextValue({
      color: '#fff',
      background: '#f40',
    });
  };
  return (
    <div>
      <p>
        生产者
        <Button type="primary" onClick={changeContext}>
          切换主题
        </Button>
      </p>
      {/* 值变化之后会让所有消费了value的组件重新渲染 */}
      <ThemeProvider value={contextValue}>
        <ClassSon />
        <Divider />
        {/* <FuncSon /> */}
        {/* <NewFuncSon /> */}
        <MemoNewFuncSon />
        <Divider />
        {/* <ConsumerCom /> */}
        <MemoConsumerCom />
        {/* 防止重新渲染 */}
        {React.useMemo(
          () => (
            <Son2 />
          ),
          [],
        )}
        <Divider />
      </ThemeProvider>
    </div>
  );
}

// 消费者
class ClassSon extends React.Component<any, any, any> {
  // If set, this.context will be set at runtime to the current value of the given Context.
  static contextType = ThemeContext;
  // 属性 "context" 将覆盖 "Component<{}, {}, any>" 中的基属性。如果是有意的，请添加初始值设定项。否则，请添加 "declare" 修饰符或删除多余的声明。
  // context!: React.ContextType<typeof ThemeContext>;
  declare context: React.ContextType<typeof ThemeContext>;
  render() {
    const color = this.context?.color;
    const background = this.context?.background;
    return <div style={{ color, background }}>static contextType 消费者</div>;
  }
}

function Son1() {
  console.log('son1');
  return <div>son1</div>;
}

function Son2() {
  console.log('son2');
  return <div>Son2</div>;
}

// 不会重新渲染
const Son22 = React.memo(() => {
  return <Son2 />;
});

function ConsumerComChild(props: any) {
  const { contextValue } = props;
  return (
    <>
      <div style={{ color: contextValue?.color, background: contextValue?.background }}>
        ConsumerCom 消费者
      </div>
      {/* <Son1 />
      <Son2 /> */}
    </>
  );
}

const MemoConsumerComChild = React.memo(ConsumerComChild);
